#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>

#include "frmem.h"
#include "frlist.h"

/*******************************************************************************
*  FUNC     :  节点内存释放
*  ARGS     :  p_st_node  (Frlist_node *)
*  RTN      :
*  NOTE     : 
*******************************************************************************/
static void __list_node_free(Frlist_node *p_st_node)
{
    if(p_st_node==NULL || p_st_node->data == NULL )
        return;
    frfree(p_st_node->data);
    return;
}

/*******************************************************************************
*  FUNC     :  查找函数
*  ARGS     :  p_st_node       (Frlist_node *)
            :  p_compare_data  (比较用数据)
*  RTN      :  比较一致返回0，其他返回1
*  NOTE     :
*******************************************************************************/
static int __list_node_find(Frlist_node *p_st_node, const void *p_compare_data)
{
    if(!p_compare_data)
        return 1;
    
    return strcmp((char *)p_compare_data, p_st_node->data);
}

/*******************************************************************************
*  FUNC     :  节点内容出力
*  ARGS     :  p_st_node       (Frlist_node *)
            :  p_outbuff       (出力内容指针)
            :  ui_buff_size    (出力内容空间)
*  RTN      :  比较一致返回0，其他返回1
*  NOTE     :
*******************************************************************************/
static void __list_node_show(Frlist_node* p_st_node, char *p_outbuff, unsigned int ui_buff_size)
{
    if(ui_buff_size <= 0 )
        return;

    snprintf(p_outbuff, ui_buff_size, "%s:", p_st_node->data);
    return;
}


void test_data1(Frlist_header *p_st_head)
{
    Frlist_node* p_st_node;
    char *p_buff;
    
    //frlist_push与frlist_add_tail功能一样
    //frlist_add_tail(p_st_head, p_st_node);
    p_st_node = frlist_node_create(frstrdup("a01"));
    frlist_push(p_st_head, p_st_node);

    p_st_node = frlist_node_create(frstrdup("a02"));
    frlist_push(p_st_head, p_st_node);

    p_st_node = frlist_node_create(frstrdup("a03"));
    frlist_push(p_st_head, p_st_node);
    
    //frlist_pop与frlist_remove_head功能一样
    //p_st_node = frlist_remove_head(p_st_head);
    p_st_node = frlist_pop(p_st_head);
    printf("pop [%s]\n", (char *)p_st_node->data);
    frlist_node_free(p_st_head, p_st_node, 0, __list_node_free);
    
    //函数查询
    p_st_node = frlist_find(p_st_head, "a03", __list_node_find);
    if(!p_st_node)
        printf("frlist_find no data\n");
    else
    {
        printf("find [%s]\n", (char *)p_st_node->data);
        frlist_node_free(p_st_head, p_st_node, 1, __list_node_free);
    }
    
    //显示连表所有数据
    printf("show all data\n");
    p_buff = frmalloc(256);
    if(!p_buff)
        return;
    *p_buff = '\0';
    frlist_show(p_st_head, p_buff, 256, __list_node_show);
    printf("[%s]\n", p_buff);
    frfree(p_buff);
    
    return;
}


void test_data2(Frlist_header *p_st_head)
{
    Frlist_node* p_st_node;
    char *p_buff;
    int i_buff_size = 256;

    p_buff = frmalloc(i_buff_size);
    if(!p_buff)
        return;

    //frlist_push与frlist_add_tail功能一样
    //frlist_add_tail(p_st_head, p_st_node);
    p_st_node = frlist_node_create(frstrdup("a01"));
    frlist_push(p_st_head, p_st_node);

    p_st_node = frlist_node_create(frstrdup("a02"));
    frlist_push(p_st_head, p_st_node);

    p_st_node = frlist_node_create(frstrdup("a03"));
    frlist_push(p_st_head, p_st_node);


    //显示连表所有数据
    printf("show all data1\nsize=%d\n", frlist_size(p_st_head));
    *p_buff = '\0';
    frlist_show(p_st_head, p_buff, i_buff_size, __list_node_show);
    printf("[%s]\n", p_buff);

    frlist_remove_from_idx(p_st_head, 0, __list_node_free);

    printf("show all data2\nsize=%d\n", frlist_size(p_st_head));
    *p_buff = '\0';
    frlist_show(p_st_head, p_buff, i_buff_size, __list_node_show);
    printf("[%s]\n", p_buff);

    frfree(p_buff);
    return;
}

void test01(void)
{
    Frlist_header *p_st_head;
    
    p_st_head = frlist_create();
    test_data1(p_st_head);
    frlist_destroy(p_st_head, __list_node_free);
    
    return;
}

void test02(void)
{
    Frlist_header st_head;
    Frlist_node* p_st_node;
    
    frlist_header_init(&st_head);
    test_data2(&st_head);
    frlist_remove_all(&st_head, __list_node_free);
    
    return;
}

int main(int argc, char *argv[])
{
    frmem_init();
    
    test02();
    
    frshow_leak();
    frmem_destroy();
    
    return 0;
}
